package com.leo.foodmaster.admin.stock.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leo.foodmaster.admin.stock.entity.*;
import com.leo.foodmaster.admin.stock.mapper.WarehouseOutRecordMapper;
import com.leo.foodmaster.admin.stock.service.IWarehouseOutRecordDetailsService;
import com.leo.foodmaster.admin.stock.service.IWarehouseOutRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leo.foodmaster.admin.stock.service.IWarehouseUserService;
import com.leo.foodmaster.admin.system.entity.UserBean;
import com.leo.foodmaster.commons.constants.RecordStatus;
import com.leo.foodmaster.commons.entity.Result;
import com.leo.foodmaster.commons.util.WebUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 出库记录 服务实现类
 * </p>
 *
 * @author Leo
 * @since 2021-09-11
 */
@Service
@AllArgsConstructor
public class WarehouseOutRecordServiceImpl extends ServiceImpl<WarehouseOutRecordMapper, WarehouseOutRecord> implements IWarehouseOutRecordService {
    private final IWarehouseUserService warehouseUserService;
    private final IWarehouseOutRecordDetailsService warehouseOutRecordDetailsService;

    /**
     * 条件分页查询出库记录列表
     * @param page 分页条件
     * @param warehouseId 仓库Id
     * @param serialNum 单据编号
     * @param status 单据状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return IPage<WarehouseOutRecord>
     */
    @Override
    public IPage<WarehouseOutRecord> getWarehouseOutRecordPageList(Page<WarehouseOutRecord> page, Long warehouseId,
                                                                   String serialNum, String status,
                                                                   String beginTime, String endTime) {
        UserBean user = WebUtils.getUser();
        // 查询仓库用户关联表
        List<WarehouseUser> warehouseUsers = warehouseUserService.list(Wrappers.lambdaQuery(WarehouseUser.class)
                .eq(WarehouseUser::getUserId, user.getId()));
        List<Long> warehouseIds = warehouseUsers.stream().map(WarehouseUser::getWarehouseId).collect(Collectors.toList());
        if (BeanUtil.isNotEmpty(warehouseId)) {
            warehouseIds = new ArrayList<>();
            warehouseIds.add(warehouseId);
        }
        LambdaQueryWrapper<WarehouseOutRecord> qw = Wrappers.lambdaQuery(WarehouseOutRecord.class)
                .eq(WarehouseOutRecord::getOrganId, user.getOrganId())
                .in(!warehouseIds.isEmpty(), WarehouseOutRecord::getWarehouseId, warehouseIds)
                .like(StrUtil.isNotBlank(serialNum), WarehouseOutRecord::getSerialNum, serialNum)
                .eq(StrUtil.isNotBlank(status), WarehouseOutRecord::getStatus, status)
                .ge(StrUtil.isNotBlank(beginTime), WarehouseOutRecord::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), WarehouseOutRecord::getCreateTime, endTime);
        return page(page, qw);
    }

    /**
     * 新增出库记录
     * @param warehouseOutRecord 出库记录信息
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> addWarehouseOutRecord(WarehouseOutRecord warehouseOutRecord) {
        // 检查出库记录信息是否正确
        String message = checkInfo(warehouseOutRecord);
        if (StringUtils.isNotBlank(message)) {
            return Result.fail(message);
        }

        // 新增出库记录主表
        warehouseOutRecord.setSerialNum("CK-" + System.currentTimeMillis());
        warehouseOutRecord.setStatus(RecordStatus.UNCHECKED);
        warehouseOutRecord.setOrganId(WebUtils.getUser().getOrganId());
        warehouseOutRecord.setCreator(WebUtils.getUser().getName());
        warehouseOutRecord.setCreateTime(LocalDateTime.now());
        boolean save = save(warehouseOutRecord);

        // 新增出库记录细表
        List<WarehouseOutRecordDetails> detailList = warehouseOutRecord.getDetailList();
        if (save) {
            for (WarehouseOutRecordDetails warehouseOutRecordDetails : detailList) {
                warehouseOutRecordDetails.setWarehouseOutRecordId(warehouseOutRecord.getId());
                warehouseOutRecordDetails.setOrganId(WebUtils.getUser().getOrganId());
                warehouseOutRecordDetails.setWarehouseId(warehouseOutRecord.getWarehouseId());
                warehouseOutRecordDetails.setWarehouseName(warehouseOutRecord.getWarehouseName());
                warehouseOutRecordDetails.setWarehouseSerialNum(warehouseOutRecord.getWarehouseSerialNum());
                warehouseOutRecordDetails.setDeptId(warehouseOutRecord.getDeptId());
                warehouseOutRecordDetails.setDeptName(warehouseOutRecord.getDeptName());
                warehouseOutRecordDetails.setCreator(WebUtils.getUser().getName());
                warehouseOutRecordDetails.setCreateTime(LocalDateTime.now());
            }
        }
        warehouseOutRecordDetailsService.saveBatch(detailList);
        return Result.success();
    }

    /**
     * 修改出库记录
     * @param warehouseOutRecord 出库记录
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> updateWarehouseOutRecord(WarehouseOutRecord warehouseOutRecord) {
        // 检查出库记录信息是否正确
        String message = checkInfo(warehouseOutRecord);
        if (StringUtils.isNotBlank(message)) {
            return Result.fail(message);
        }
        // 根据主表Id删除细表记录
        boolean remove = warehouseOutRecordDetailsService.remove(Wrappers.lambdaUpdate(WarehouseOutRecordDetails.class)
                .eq(WarehouseOutRecordDetails::getWarehouseOutRecordId, warehouseOutRecord.getId()));
        // 新增细表
        if (remove) {
            List<WarehouseOutRecordDetails> detailList = warehouseOutRecord.getDetailList();
            for (WarehouseOutRecordDetails warehouseOutRecordDetails : detailList) {
                warehouseOutRecordDetails.setWarehouseOutRecordId(warehouseOutRecord.getId());
                warehouseOutRecordDetails.setOrganId(WebUtils.getUser().getOrganId());
                warehouseOutRecordDetails.setWarehouseId(warehouseOutRecord.getWarehouseId());
                warehouseOutRecordDetails.setWarehouseName(warehouseOutRecord.getWarehouseName());
                warehouseOutRecordDetails.setWarehouseSerialNum(warehouseOutRecord.getWarehouseSerialNum());
                warehouseOutRecordDetails.setDeptId(warehouseOutRecord.getDeptId());
                warehouseOutRecordDetails.setDeptName(warehouseOutRecord.getDeptName());
                warehouseOutRecordDetails.setCreator(WebUtils.getUser().getName());
                warehouseOutRecordDetails.setCreateTime(LocalDateTime.now());
            }
            warehouseOutRecordDetailsService.saveBatch(detailList);
        }
        // 修改主表
        warehouseOutRecord.setUpdateUser(WebUtils.getUser().getName());
        warehouseOutRecord.setUpdateTime(LocalDateTime.now());
        updateById(warehouseOutRecord);
        return Result.success();
    }

    /**
     * 删除出库清单
     * @param id 出库单Id
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> deleteWarehouseOutRecord(Long id) {
        // 只能删除未审核 和 审核不通过的出库清单
        WarehouseOutRecord warehouseOutRecord = getById(id);
        if (!(RecordStatus.UNCHECKED.equals(warehouseOutRecord.getStatus())
                || RecordStatus.CHECK_NOT_PASS.equals(warehouseOutRecord.getStatus()))) {
            return Result.fail("只能删除未审核和审核不通过的出库清单");
        }
        // 删除细表
        boolean remove = warehouseOutRecordDetailsService.remove(Wrappers.lambdaUpdate(WarehouseOutRecordDetails.class)
                .eq(WarehouseOutRecordDetails::getWarehouseOutRecordId, id));
        // 删除主表
        if (remove) {
            removeById(id);
        }
        return Result.success();
    }

    /**
     * 审核出库记录
     * @param warehouseOutRecord 入库记录
     * @return Result<Object>
     */
    @Override
    public Result<Object> checkWarehouseOutRecord(WarehouseOutRecord warehouseOutRecord) {
        UserBean user = WebUtils.getUser();
        warehouseOutRecord.setCheckBy(user.getName());
        warehouseOutRecord.setCheckById(user.getId());
        warehouseOutRecord.setCheckTime(LocalDateTime.now());
        warehouseOutRecord.setUpdateUser(user.getName());
        warehouseOutRecord.setUpdateTime(LocalDateTime.now());
        updateById(warehouseOutRecord);
        return Result.success();
    }

    /**
     * 检查出库记录信息是否正确
     * @param warehouseOutRecord 出库记录信息
     * @return String
     */
    private String checkInfo(WarehouseOutRecord warehouseOutRecord) {
        String message = null;
        // 出库记录详细信息不能为空
        List<WarehouseOutRecordDetails> detailList = warehouseOutRecord.getDetailList();
        if (detailList.isEmpty()) {
            message = "出库记录详细信息不能为空";
        }

        return message;
    }

}
